package com.gobang.domain.dto;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import lombok.Data;

import java.io.Serializable;

/**
 * 分页请求参数封装
 * 
 * @author Gobang Team
 * @version 1.0.0
 */
@Data
public class PageRequest implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * 默认页码
     */
    public static final int DEFAULT_PAGE_NUM = 1;

    /**
     * 默认每页大小
     */
    public static final int DEFAULT_PAGE_SIZE = 10;

    /**
     * 最小每页大小
     */
    public static final int MIN_PAGE_SIZE = 1;

    /**
     * 最大每页大小（防止一次性查询过多数据）
     */
    public static final int MAX_PAGE_SIZE = 100;

    /**
     * 当前页码（从1开始）
     */
    @Min(value = 1, message = "页码必须大于等于1")
    private Integer pageNum = DEFAULT_PAGE_NUM;

    /**
     * 每页大小
     */
    @Min(value = MIN_PAGE_SIZE, message = "每页大小必须大于等于" + MIN_PAGE_SIZE)
    @Max(value = MAX_PAGE_SIZE, message = "每页大小不能超过" + MAX_PAGE_SIZE)
    private Integer pageSize = DEFAULT_PAGE_SIZE;

    /**
     * 排序字段（可选）
     * 例如：created_at、updated_at
     */
    private String orderBy;

    /**
     * 排序方向（可选）
     * asc: 升序, desc: 降序
     */
    private String orderDirection = "desc";

    /**
     * 无参构造函数
     */
    public PageRequest() {
    }

    /**
     * 构造函数
     * 
     * @param pageNum 页码
     * @param pageSize 每页大小
     */
    public PageRequest(Integer pageNum, Integer pageSize) {
        this.pageNum = pageNum != null && pageNum > 0 ? pageNum : DEFAULT_PAGE_NUM;
        this.pageSize = pageSize != null && pageSize > 0 ? pageSize : DEFAULT_PAGE_SIZE;
        // 限制最大页大小
        if (this.pageSize > MAX_PAGE_SIZE) {
            this.pageSize = MAX_PAGE_SIZE;
        }
    }

    /**
     * 构造函数（带排序）
     * 
     * @param pageNum 页码
     * @param pageSize 每页大小
     * @param orderBy 排序字段
     * @param orderDirection 排序方向
     */
    public PageRequest(Integer pageNum, Integer pageSize, String orderBy, String orderDirection) {
        this(pageNum, pageSize);
        this.orderBy = orderBy;
        this.orderDirection = orderDirection;
    }

    /**
     * 创建默认分页请求
     * 
     * @return 默认分页请求（pageNum=1, pageSize=10）
     */
    public static PageRequest ofDefault() {
        return new PageRequest();
    }

    /**
     * 创建分页请求
     * 
     * @param pageNum 页码
     * @param pageSize 每页大小
     * @return 分页请求
     */
    public static PageRequest of(Integer pageNum, Integer pageSize) {
        return new PageRequest(pageNum, pageSize);
    }

    /**
     * 创建分页请求（带排序）
     * 
     * @param pageNum 页码
     * @param pageSize 每页大小
     * @param orderBy 排序字段
     * @param orderDirection 排序方向
     * @return 分页请求
     */
    public static PageRequest of(Integer pageNum, Integer pageSize, String orderBy, String orderDirection) {
        return new PageRequest(pageNum, pageSize, orderBy, orderDirection);
    }

    /**
     * 转换为MyBatis-Plus的Page对象
     * 
     * @param <T> 实体类型
     * @return MyBatis-Plus的Page对象
     */
    public <T> Page<T> toPage() {
        return new Page<>(this.pageNum, this.pageSize);
    }

    /**
     * 转换为MyBatis-Plus的Page对象（带排序）
     * 
     * @param <T> 实体类型
     * @return MyBatis-Plus的Page对象
     */
    public <T> Page<T> toPageWithOrder() {
        Page<T> page = new Page<>(this.pageNum, this.pageSize);
        
        if (this.orderBy != null && !this.orderBy.trim().isEmpty()) {
            // 判断排序方向
            boolean isAsc = "asc".equalsIgnoreCase(this.orderDirection);
            
            if (isAsc) {
                page.addOrder(com.baomidou.mybatisplus.core.metadata.OrderItem.asc(this.orderBy));
            } else {
                page.addOrder(com.baomidou.mybatisplus.core.metadata.OrderItem.desc(this.orderBy));
            }
        }
        
        return page;
    }

    /**
     * 判断是否有排序
     * 
     * @return 是否有排序
     */
    public boolean hasOrder() {
        return this.orderBy != null && !this.orderBy.trim().isEmpty();
    }

    /**
     * 判断是否为升序
     * 
     * @return 是否为升序
     */
    public boolean isAsc() {
        return "asc".equalsIgnoreCase(this.orderDirection);
    }

    /**
     * 判断是否为降序
     * 
     * @return 是否为降序
     */
    public boolean isDesc() {
        return "desc".equalsIgnoreCase(this.orderDirection);
    }

    /**
     * 计算偏移量（用于某些场景）
     * 
     * @return 偏移量
     */
    public long getOffset() {
        return (long) (this.pageNum - 1) * this.pageSize;
    }

    /**
     * 设置页码（带校验）
     */
    public void setPageNum(Integer pageNum) {
        this.pageNum = pageNum != null && pageNum > 0 ? pageNum : DEFAULT_PAGE_NUM;
    }

    /**
     * 设置每页大小（带校验和限制）
     */
    public void setPageSize(Integer pageSize) {
        if (pageSize == null || pageSize <= 0) {
            this.pageSize = DEFAULT_PAGE_SIZE;
        } else if (pageSize > MAX_PAGE_SIZE) {
            this.pageSize = MAX_PAGE_SIZE;
        } else {
            this.pageSize = pageSize;
        }
    }

}

